

#pragma once

#include "../DefinesCore.hpp"

#include <string>
#include <vector>
#ifdef CYBERTRON_WIN
#include <windows.h>
#else
#include <sys/types.h>
#endif

CYBERTRON_BEGIN

struct proc_stat_t;

class ProcessHandle
{
public:
	friend struct proc_stat_t;
	friend class UtilProcess;
	CybertronCoreAPI bool isValid() const;

#ifdef CYBERTRON_WIN
	HANDLE mHandle = nullptr;
#else
	pid_t mHandle = -1;
#endif
};

class UtilProcess
{
public:
	// If we need a return value, we will start the process and wait until
	// it finishes, fill in the return value
        // envs is only supported on Linux currently
	CybertronCoreAPI static bool start(
		const std::string& executable,
		const std::string& workPath,
		const std::vector<std::string>& parameters,
		ProcessHandle& process, 
		const std::vector<std::string>& envs,
		uint32_t* returnValue = nullptr, 
		bool closeforkfd = false);

	CybertronCoreAPI static bool startWindowsBat(
		const std::string& executable,
		const std::string& workPath,
		const std::vector<std::string>& parameters,
		ProcessHandle& process,
		const std::vector<std::string>& envs,
		bool isService = false);

	CybertronCoreAPI static bool startex(
		const std::string& executable,
		const std::string& workPath,
		const std::vector<std::string>& parameters,
		ProcessHandle& process,
		const std::vector<std::string>& envs,
		bool isService = false,
		uint32_t* returnValue = nullptr,
		bool closeforkfd = false);
	CybertronCoreAPI static bool isRunning(ProcessHandle process);

	CybertronCoreAPI static ProcessHandle openExisting(const std::string& executableName);

	CybertronCoreAPI static void terminateAndCloseHandleNotWait(ProcessHandle& process);

	CybertronCoreAPI static void terminateAndCloseHandle(ProcessHandle& process);

	CybertronCoreAPI static void closeHandle(ProcessHandle& process);
};


CYBERTRON_END
